package com.grape.utils;

import com.alibaba.fastjson.JSONException;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.grape.enums.RedisKeyEnums;
import com.grape.redis.service.IRedisService;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.xml.ws.http.HTTPException;
import java.lang.reflect.Field;


/**
 * 类描述： 发送验证码工具类
 *
 * @author  putao
 * @email   2628279194@qq.com
 */
@Component
@AllArgsConstructor
public class SendCodeUtils {

    private final IRedisService redisService;

    private static final Logger logger = LoggerFactory.getLogger(SendCodeUtils.class);

    /**
     * 发送短信验证码
     * @param phone     手机号码
     * @param codeSB    验证码
     * @return          发送结果
     */
    public Boolean sendCode(String phone, StringBuilder codeSB) {
        String code = StringUtils.generateCode();
        logger.info("手机号码：{}，验证码为：{}", phone, code);
        codeSB.append(code);
        // 发送消息，消费消息时调用发送短信接口
//        sendCodeByPhone(code, phone);
        redisService.setAndTime(RedisKeyEnums.VERIFY_CODE_KEY.join(phone), code, RedisKeyEnums.VERIFY_CODE_KEY.getTime());
        return true;
    }

    /**
     * 根据手机号码发送短信
     * @param phone     手机号码
     * @param key       存入redis的标识
     * @param time      时间
     * @param codeSB    验证码内容
     * @return          发送结果
     */
    public Boolean sendCode(String phone, String key, Long time, StringBuilder codeSB) {
        String code = StringUtils.generateCode();
        logger.info("手机号码：{}，验证码为：{}", phone, code);
        codeSB.append(code);
        // 发送消息，消费消息时调用发送短信接口
//        sendCodeByPhone(code, phone);
        redisService.setAndTime(key, code, time);
        return true;
    }

    /**
     * 自定义短信内容发送
     * @param code  短信内容
     * @param phone 用户手机号
     * @return      发送结果
     */
    public boolean sendCodeByPhone(String code, String phone) {
        // 短信应用SDK AppID
        int appid = 1400632169; // 1400开头

        // 短信应用SDK AppKey
        String appkey = "4436971e5d6cb3839eb1cb8461689099";

        // 短信模板ID，需要在短信应用中申请
        int templateId = 1300824; // NOTE: 这里的模板ID`7839`只是一个示例，真实的模板ID需要在短信控制台中申请

        // 需要发送短信的手机号码
        String[] phoneNumbers = {phone};
        //templateId7839对应的内容是"您的验证码是: {1}"
        String smsSign = "程序员葡萄"; // NOTE: 这里的签名"腾讯云"只是一个示例，真实的签名需要在短信控制台中申请，另外签名参数使用的是`签名内容`，而不是`签名ID`

        try {
            String[] params = {code};//数组具体的元素个数和模板中变量个数必须一致，例如事例中templateId:5678对应一个变量，参数数组中元素个数也必须是一个
            SmsSingleSender sSender = new SmsSingleSender(appid, appkey);
            SmsSingleSenderResult result = sSender.sendWithParam("86", phoneNumbers[0],
                    templateId, params, smsSign, "", "");  // 签名参数未提供或者为空时，会使用默认签名发送短信
            System.out.println(result);
            Class<? extends SmsSingleSenderResult> aClass = result.getClass();
            // 获取类中声明的字段
            Field[] fields = aClass.getDeclaredFields();
            for (Field field : fields) {
                // 避免 can not access a member of class com.java.test.Person with modifiers "private"
                field.setAccessible(true);
                try {
                    if ("result".equals(field.getName())) {
                        if (Integer.parseInt(field.get(result) + "") == 0) {
                            logger.error("短信发送成功,验证码是 " + code);
                            // 存入redis
                            redisService.setAndTime(RedisKeyEnums.PHONE_CODE.join(phone), code, RedisKeyEnums.PHONE_CODE.getTime());
                            return true;
                        }
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        } catch (HTTPException e) {
            // HTTP响应码错误
            e.printStackTrace();
        } catch (JSONException e) {
            // json解析错误
            e.printStackTrace();
        } catch (Exception e) {
            // 网络IO错误
            e.printStackTrace();
        }
        return false;
    }

}
